﻿/************************************
Usage:

var _handler:flash2js = new flash2();
_handler.init(); // 初始化

_handler.reg("YOUR_FLASH_FUNCTION", someFlashFunction);	// you need to reg the function for javascript calling.
_handler.callJS("JS_FUNCTION", _arg[optional]);	// JS_FUNCTION:String is needed, _arg was unlimit, base on your JS_FUNCTION's input.
_handler.assignVar("JS_VAR", _value);			// JS_VAR:String must relatived to javascript,
												// f not it will create a new one. the value will trying to
												// exchange to it's type on client side.

function  someFlashFunction(p:*,a:*,c:*,k:*):void{trace(p+","+a+","+c+","+k)}//fn

************************************/
package com.cf.core.network{
	import com.cf.core.events.LoadEvent;
	import com.cf.core.Utils.debug;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.external.ExternalInterface;
	import flash.utils.Timer;
	import flash.system.Security;
	import flash.system.Capabilities;
	public class flash2js extends EventDispatcher{
		private var _pingTime:int; // 重試連接的嘗試數
		private var _maxretry:int; // 每次重試最大值
		private var _curretry:int; // 現在 reping 記錄數
		public function flash2js():void{
			_curretry = 0;
			_maxretry = 100;
			_pingTime = 500;
		}//fn
		
		public function init() {
			if (ExternalInterface.available) {
				try {
					if (checkJSReady()) {
						dispatchEvent(new LoadEvent(LoadEvent.ONLOAD));
						debug.msg("JavaScript is ready.");
						_curretry=0;
					} else {
						debug.msg("JavaScript is not ready, creating timer.");
						var readyTimer:Timer = new Timer(_pingTime, 0);
						readyTimer.addEventListener(TimerEvent.TIMER, pingJS);
						readyTimer.start();
					}//if
				} catch (error:SecurityError) {
					debug.msg("A SecurityError occurred: " + error.message);
					debug.msg("Current Security.sandboxType is: " + Security.sandboxType);
					dispatchEvent(new LoadEvent(LoadEvent.FAIL));
				} catch (error:Error) {
					debug.msg("An Error occurred: " + error.message);
					dispatchEvent(new LoadEvent(LoadEvent.FAIL));
				}//try
			} else {
				debug.msg("External interface is not available for this container.");
				dispatchEvent(new LoadEvent(LoadEvent.FAIL));
			}//if
			//
			// Open tunnel to Javscript.
			//
			this.reg("getFlashInfo", getFlashInfo);
		}//fn
		public function reg(_fs:String, _fn:Function):void{
			ExternalInterface.addCallback(_fs,_fn);
		}//fn
		public function getFlashInfo():Object{
			var _obj=new Object;
			_obj.os = Capabilities.os;
			_obj.version = Capabilities.version;
			_obj.avHardwareDisable = Capabilities.avHardwareDisable;
            _obj.hasAccessibility = Capabilities.hasAccessibility;
            _obj.hasAudio = Capabilities.hasAudio;
            _obj.hasAudioEncoder = Capabilities.hasAudioEncoder;
            _obj.hasEmbeddedVideo = Capabilities.hasEmbeddedVideo;
            _obj.hasMP3 = Capabilities.hasMP3;
            _obj.hasPrinting = Capabilities.hasPrinting;
            _obj.hasScreenBroadcast = Capabilities.hasScreenBroadcast;
            _obj.hasScreenPlayback = Capabilities.hasScreenPlayback;
            _obj.hasStreamingAudio = Capabilities.hasStreamingAudio;
            _obj.hasVideoEncoder = Capabilities.hasVideoEncoder;
            _obj.isDebugger = Capabilities.isDebugger;
            _obj.language = Capabilities.language;
            _obj.localFileReadDisable = Capabilities.localFileReadDisable;
            _obj.manufacturer = Capabilities.manufacturer;
            _obj.pixelAspectRatio = Capabilities.pixelAspectRatio;
            _obj.playerType = Capabilities.playerType;
            _obj.screenColor = Capabilities.screenColor;
            _obj.screenDPI = Capabilities.screenDPI;
            _obj.screenResolutionX = Capabilities.screenResolutionX;
            _obj.screenResolutionY = Capabilities.screenResolutionY;
            _obj.serverString = Capabilities.serverString;
			return _obj;
		}//fn
		// 取得 Javascript 能否連接的值
		private function checkJSReady():Boolean {
			var isReady:Boolean = ExternalInterface.call("flash2js.connection");// flash2js.connection // isReady
			return isReady;
		}//fn
		// Js 連接重試
		private function pingJS(e:TimerEvent):void {
			_curretry++;
			debug.msg("Checking JavaScript status...["+_curretry+"]");
			var isReady:Boolean =  checkJSReady();
			if (isReady) {
				dispatchEvent(new LoadEvent(LoadEvent.ONLOAD));
				debug.msg("JavaScript is ready.");
				Timer(e.target).stop();
				_curretry=0;
			}else{
				if(_curretry>=_maxretry){
					dispatchEvent(new LoadEvent(LoadEvent.FAIL));
					debug.msg("JavaScript has no response.");
					Timer(e.target).stop();
					_curretry=0;
				}//if
			}//if
		}//fn
		public function callJS(_fn:String, ...arg):void{
			var _obj:Object = new Object;
			_obj.fn = _fn;
			_obj.arg = arg;
			ExternalInterface.call("flash2js.callJsFn", _obj);
		}//fn
		public function assignVar(_var:String, _value:*):void{
			var _obj:Object = new Object;
			_obj.name = _var;
			_obj.value = _value;
			ExternalInterface.call("flash2js.assignJsVar", _obj);
		}//fn
	}//class
}//package